#pragma once
#include <iostream>
#include <sys/epoll.h>
#include "Log.hpp"
#include "Common.hpp"

using namespace std;
using namespace LogModule;

class Epoller
{
public:
    Epoller()
    :_epfd(-1)
    {
        _epfd=epoll_create(256);    //构造epoll模型
        if(_epfd<0) 
        {
            LOG(LogLevel::FATAL)<<"epoll_create error";
            exit(EPOLL_CREATE_ERR);
        }
        LOG(LogLevel::INFO)<<"epoll_create success";
    }
    void AddEvent(int sockfd,uint32_t events)   //添加关心的事件
    {
        struct epoll_event ev;
        ev.events=events;
        ev.data.fd=sockfd;
        int n=epoll_ctl(_epfd,EPOLL_CTL_ADD,sockfd,&ev);
        if(n<0)
        {
            LOG(LogLevel::FATAL)<<"epoll_ctl error";
            exit(EPOLL_CTL_ERR);
        }
        LOG(LogLevel::INFO)<<"epoll_ctl success";
    }
    int WaitEvents(struct epoll_event revs[],int size,int timeout)  //就绪队列中就绪事件个数
    {
        int n=epoll_wait(_epfd,revs,size,timeout);
        if(n<0)
        {
            LOG(LogLevel::WARNING)<<"epoll_wait error";
            return n;
        }
        else if(n==0)
        {
            LOG(LogLevel::WARNING)<<"epoll_wait timeout";
            return n;
        }
        else
        {
            LOG(LogLevel::INFO)<<"读事件就绪";
            return n;
        }
    }
    void ModEvent(int sockfd,uint32_t events)
    {
        struct epoll_event ev;
        ev.data.fd=sockfd;
        ev.events=events;
        int n=epoll_ctl(_epfd,EPOLL_CTL_MOD,sockfd,&ev);
        if(n<0)
        {
            LOG(LogLevel::FATAL)<<"mov_event error";
            exit(EPOLL_CTL_ERR);
        }
        LOG(LogLevel::INFO)<<"mov_event success";
    }
    void DelEvent(int sockfd)
    {
        int n=epoll_ctl(_epfd,EPOLL_CTL_DEL,sockfd,nullptr);
        if(n<0)
        {
            LOG(LogLevel::FATAL)<<"del_event error";
            exit(EPOLL_CTL_ERR);
        }
        LOG(LogLevel::INFO)<<"del_event success";
    }
    ~Epoller()
    {
        
    }  
private:
    int _epfd;
};